package com.example.jobtask.executor;

import com.example.jobtask.entity.JobTask;
import com.example.jobtask.util.DynamicClassLoader;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 任务执行器，负责反射调用任务方法
 */
@Component
public class TaskExecutor {
    
    private static final Logger logger = LoggerFactory.getLogger(TaskExecutor.class);
    
    @Autowired
    private DynamicClassLoader dynamicClassLoader;
    
    private final ObjectMapper objectMapper = new ObjectMapper();
    
    /**
     * 执行任务
     * @param jobTask 任务对象
     * @return 执行结果
     */
    public Object executeTask(JobTask jobTask) {
        try {
            logger.info("开始执行任务: {}", jobTask.getTaskName());
            
            // 获取目标类
            Class<?> targetClass = loadTargetClass(jobTask);
            
            // 创建类实例
            Object instance = targetClass.getDeclaredConstructor().newInstance();
            
            // 解析方法参数
            Object[] methodParams = parseMethodParams(jobTask.getMethodParams());
            
            // 获取方法参数类型
            Class<?>[] paramTypes = getParamTypes(methodParams);
            
            // 获取目标方法
            Method targetMethod = targetClass.getMethod(jobTask.getTargetMethod(), paramTypes);
            
            // 执行方法
            Object result = targetMethod.invoke(instance, methodParams);
            
            logger.info("任务执行成功: {}, 结果: {}", jobTask.getTaskName(), result);
            return result;
            
        } catch (Exception e) {
            logger.error("执行任务失败: " + jobTask.getTaskName(), e);
            throw new RuntimeException("执行任务失败: " + jobTask.getTaskName(), e);
        }
    }
    
    /**
     * 加载目标类
     */
    private Class<?> loadTargetClass(JobTask jobTask) {
        String className = jobTask.getTargetClass();
        String javaFilePath = jobTask.getJavaFilePath();
        
        try {
            // 如果有Java文件路径，先尝试从文件加载
            if (javaFilePath != null && !javaFilePath.trim().isEmpty()) {
                if (dynamicClassLoader.javaFileExists(javaFilePath)) {
                    return dynamicClassLoader.loadClassFromFile(javaFilePath, className);
                } else {
                    logger.warn("Java文件不存在: {}, 尝试加载已编译的类", javaFilePath);
                }
            }
            
            // 尝试加载已编译的类
            try {
                return dynamicClassLoader.loadCompiledClass(className);
            } catch (Exception e) {
                logger.warn("无法从编译目录加载类，尝试从类路径加载: {}", className);
                // 最后尝试从类路径加载
                return Class.forName(className);
            }
            
        } catch (Exception e) {
            throw new RuntimeException("无法加载目标类: " + className, e);
        }
    }
    
    /**
     * 解析方法参数
     */
    private Object[] parseMethodParams(String methodParamsJson) {
        if (methodParamsJson == null || methodParamsJson.trim().isEmpty()) {
            return new Object[0];
        }
        
        try {
            // 假设参数是JSON数组格式
            List<?> paramsList = objectMapper.readValue(methodParamsJson, List.class);
            return paramsList.toArray();
        } catch (JsonProcessingException e) {
            logger.warn("解析方法参数失败，尝试作为单个字符串参数: {}", methodParamsJson);
            // 如果解析失败，作为单个字符串参数
            return new Object[]{methodParamsJson};
        }
    }
    
    /**
     * 获取参数类型数组
     */
    private Class<?>[] getParamTypes(Object[] params) {
        if (params == null || params.length == 0) {
            return new Class<?>[0];
        }
        
        Class<?>[] types = new Class<?>[params.length];
        for (int i = 0; i < params.length; i++) {
            if (params[i] == null) {
                types[i] = Object.class;
            } else {
                types[i] = params[i].getClass();
                // 处理基本数据类型的包装类
                if (types[i] == Integer.class) {
                    types[i] = int.class;
                } else if (types[i] == Long.class) {
                    types[i] = long.class;
                } else if (types[i] == Double.class) {
                    types[i] = double.class;
                } else if (types[i] == Float.class) {
                    types[i] = float.class;
                } else if (types[i] == Boolean.class) {
                    types[i] = boolean.class;
                } else if (types[i] == Short.class) {
                    types[i] = short.class;
                } else if (types[i] == Byte.class) {
                    types[i] = byte.class;
                } else if (types[i] == Character.class) {
                    types[i] = char.class;
                }
            }
        }
        return types;
    }
    
    /**
     * 验证任务是否可执行
     */
    public boolean validateTask(JobTask jobTask) {
        try {
            // 验证类是否可加载
            Class<?> targetClass = loadTargetClass(jobTask);
            
            // 验证方法是否存在
            Object[] methodParams = parseMethodParams(jobTask.getMethodParams());
            Class<?>[] paramTypes = getParamTypes(methodParams);
            
            Method targetMethod = targetClass.getMethod(jobTask.getTargetMethod(), paramTypes);
            
            logger.info("任务验证成功: {}", jobTask.getTaskName());
            return true;
            
        } catch (Exception e) {
            logger.error("任务验证失败: " + jobTask.getTaskName(), e);
            return false;
        }
    }
}